package dolf.window;

import java.awt.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
import javax.swing.*;
import java.awt.event.*;

import dolf.game.*;

import dolf.objects.weapons.Weapon;


public class BuyWindow extends Window {
	private class wAttrib {
		wAttrib(String k, String n, String d, String t, Integer p, javax.swing.ImageIcon i) {
			klass = k;
			name = n;
			description = d;
			type = t;
			price = p;
			icon = i;
		}
		public String klass;
		public String name;
		public String description;
		public String type;
		public int price;
		public javax.swing.ImageIcon icon;
		
		public String toString() {
			String s = klass+name+description+type+price+"\n";
			return s;
		}
	}
	
	private static final long serialVersionUID = 1L;
	private static BuyWindow instance = new BuyWindow();
	
	private List<Player> players;
	
	private boolean started = false;
	private boolean complete = false;
	
	private Player firstPlayer;
	
	private int currPlayer = 0;
	
	private int currTab = 0;
	
	private BuyWindow() {
		initialize();
		
		getContentPane().setLayout(new BoxLayout(getContentPane(),BoxLayout.PAGE_AXIS));
		addWindowListener(new WindowListener() {

			public void windowActivated(WindowEvent arg0) {}
			public void windowClosed(WindowEvent arg0) {}
			public void windowClosing(WindowEvent arg0) {
				complete = true;
				Level.getInstance().setAktualPlayer(firstPlayer);
				dispose();
			}
			public void windowDeactivated(WindowEvent arg0) {}
			public void windowDeiconified(WindowEvent arg0) {}
			public void windowIconified(WindowEvent arg0) {}
			public void windowOpened(WindowEvent arg0) {}
		});
	}
	protected void initialize() {
		super.initialize(SystemMessagesHandler.getInstance().getMessages().getString("buywindow"));
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
	}

	public static BuyWindow getInstance() {
		return instance;
	}
	
	public void draw(List<Player> pl) {
		if (started == false) {
			firstPlayer = Level.getInstance().getAktualPlayer();
		}
		players = pl;
		started = true;
		
		getContentPane().removeAll();
		
		if (currPlayer < 0) currPlayer = 0;
		
		if ( currPlayer >= players.size() ) {
			complete = true;
			dispose();
		} else {
			initialize();
			add(getHeader());
			add(new javax.swing.JSeparator());
			add(getBody());
			add(new javax.swing.JSeparator());
			add(getButtonPane());
			pack();
			if (!isVisible()) setLocationRelativeTo(MainWindow.getInstance());
			setVisible(true);
		}
	}
	
	public JPanel getHeader() {
		JPanel headerPane = new JPanel();
		
		headerPane.setLayout(new BoxLayout(headerPane, BoxLayout.LINE_AXIS));
		headerPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
		JLabel nameL = new JLabel(players.get(currPlayer).getName());
		nameL.setPreferredSize(new Dimension(300,25));
		headerPane.add(nameL);
		headerPane.add(Box.createRigidArea(new Dimension(10,0)));
		headerPane.add(Box.createHorizontalGlue());
		
		
		headerPane.add(new JLabel(SystemMessagesHandler.getInstance().getMessages().getString("money")+": " + Integer.toString(players.get(currPlayer).getMoney())));
		
		
		headerPane.setVisible(true);
		
		return headerPane;
	}
	
	public JPanel getBody() {
		
		// get list of currently installed Weapons from dolf/objects/weapons.index
		JPanel buyPane = new JPanel();
		buyPane.setPreferredSize(new Dimension(460,330));
		
		final JTabbedPane tabPane = new JTabbedPane(JTabbedPane.TOP);
		tabPane.setAlignmentX(JTabbedPane.LEFT_ALIGNMENT);
		tabPane.setPreferredSize(new Dimension(450,320));
		
		LinkedList<LinkedList<wAttrib>> list = getLists(getWeaponNames());
		
		for (int i = 0; i < list.size(); i++) { //tabs erstellen
			JPanel p = new JPanel();
			p.setLayout(new GridBagLayout());
			
			GridBagConstraints c = new GridBagConstraints();
			c.anchor = GridBagConstraints.WEST;
			c.insets = new Insets(0,5,5,5);
			c.gridx = 1;
		    c.gridy = 0;
		    
		    p.add(new JLabel("<html><body><u>"+SystemMessagesHandler.getInstance().getMessages().getString("name")+":</u></body></html>", SwingConstants.RIGHT), c);
		    c.gridx = 2;
		    c.gridy = 0;
		    p.add(new JLabel("<html><body><u>"+SystemMessagesHandler.getInstance().getMessages().getString("price")+":</u></body></html>", SwingConstants.RIGHT), c);
			
		    c.gridx = 3;
		    c.gridy = 0;
		    p.add(new JLabel("<html><body><u>"+SystemMessagesHandler.getInstance().getMessages().getString("current_amount")+":</u></body></html>", SwingConstants.RIGHT), c);
			
		    c.gridx = 4;
		    c.gridy = 0;
		    p.add(new JLabel("<html><body><u>"+SystemMessagesHandler.getInstance().getMessages().getString("possible_amount")+":</u></body></html>", SwingConstants.RIGHT), c);
			
		    boolean buyable = false;			
			for (int j = 0; j < list.get(i).size(); j++) { //tabs erstellen
				final wAttrib a = list.get(i).get(j);
				
				c.gridx = 0;
			    c.gridy = j+1;
				p.add(new JLabel( a.icon), c);
				
				
				JLabel nameLabel = new JLabel(a.name);
				nameLabel.setPreferredSize(new Dimension(150,25));
				nameLabel.setToolTipText(a.description);
				c.gridx = 1;
			    c.gridy = j+1;
				p.add(nameLabel, c);
				
				
				c.gridx = 2;
			    c.gridy = j+1;
			    JLabel priceLabel = new JLabel( Integer.toString(a.price), SwingConstants.RIGHT);
			    priceLabel.setPreferredSize(new Dimension(30,25));
			    p.add(priceLabel,c);
				
				c.gridx = 3;
			    c.gridy = j+1;
				p.add(new JLabel( Integer.toString( players.get(currPlayer).getWeaponAmount(a.name)), SwingConstants.RIGHT), c);
				
				c.gridx = 4;
			    c.gridy = j+1;
			    if (a.price == 0) System.out.println(a.name+" war null!");
			    else {
			    	int buyAmount = players.get(currPlayer).getMoney()/a.price;
			    	if (buyAmount > 0) buyable = true;
			    	p.add(new JLabel( Integer.toString( buyAmount) , SwingConstants.RIGHT), c);
			    }
			    final Player pl = players.get(currPlayer);
			    
			    c.gridx = 5;
			    c.gridy = j+1;
			    JButton sellButton = new JButton(new javax.swing.ImageIcon(getClass().getClassLoader().getResource("dolf/gfx/window/sell.png")));
			    sellButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getClassLoader().getResource("dolf/gfx/window/sell.png")));
			    sellButton.setContentAreaFilled(false);
				sellButton.setBorderPainted(false);
				sellButton.setFocusPainted(false);
				sellButton.setMargin(new Insets(0,0,0,0));
				sellButton.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
				sellButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						pl.setMoney((int) (pl.getMoney() + Integer.parseInt(ConfigurationHandler.getInstance().getProperty("sell_percentage"))/100.0*a.price));
						pl.removeWeapon(a.name);
						currTab = tabPane.getSelectedIndex();
						PlayerDisplay.getInstance().draw();
						draw();
					}
				});
				
					
				if (pl.getWeaponAmount(a.name) > 0) p.add(sellButton, c);
				else {
					JLabel l = new JLabel();
					l.setPreferredSize(new Dimension(25,25));
					p.add(l,c);
				}
			    
			    
			    
			    
				c.gridx = 6;
			    c.gridy = j+1;
			    JButton buyButton = new JButton(new javax.swing.ImageIcon(getClass().getClassLoader().getResource("dolf/gfx/window/cart.png")));
			    buyButton.setDisabledIcon(new javax.swing.ImageIcon(getClass().getClassLoader().getResource("dolf/gfx/window/cart_disabled.png")));
			    buyButton.setContentAreaFilled(false);
				buyButton.setBorderPainted(false);
				buyButton.setFocusPainted(false);
				buyButton.setMargin(new Insets(0,0,0,0));
				buyButton.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
				buyButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						if (players.get(currPlayer).getMoney() < a.price) return;
						
						try {
							players.get(currPlayer).addWeapon( (Weapon) Class.forName(a.klass).newInstance());
							players.get(currPlayer).setMoney(players.get(currPlayer).getMoney()-a.price);
							currTab = tabPane.getSelectedIndex();
							PlayerDisplay.getInstance().draw();
							draw();
						}
						catch (Exception f) {
							System.err.println("failed to add weapon "+a.name+" to player "+ players.get(currPlayer).getName());
						}
					}
				});
				if (players.get(currPlayer).getMoney() < a.price){
					buyButton.setEnabled(false);
				}
					
				p.add(buyButton, c);
			
			}
			JPanel t = new JPanel(new FlowLayout(FlowLayout.LEFT));
			t.add(p);
			JScrollPane sP = new JScrollPane(t);
			sP.getVerticalScrollBar().setUnitIncrement(10);
			sP.setViewportBorder(BorderFactory.createEmptyBorder(5,0,5,0));
			sP.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
			if (!buyable) tabPane.insertTab("<html><font color=999999>"+list.get(i).get(0).type+"</font></html>", null, sP, null, i);
			else tabPane.insertTab(list.get(i).get(0).type, null, sP, null, i);
		}
		buyPane.add(tabPane);
		
		tabPane.setSelectedIndex(currTab);
		buyPane.setVisible(true);
		return buyPane;
	}
	
	private JPanel getButtonPane() {
		JPanel buttonPane = new JPanel();
		
		buttonPane.setVisible(true);
		buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));
		buttonPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
		
		
		JButton previousButton = new JButton(SystemMessagesHandler.getInstance().getMessages().getString("previous_player"));
		
		if (currPlayer == 0) previousButton.setEnabled(false);
		
		previousButton.setMnemonic('p');
		previousButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				currTab = 0;
				currPlayer--;
				Level.getInstance().setAktualPlayer(players.get(currPlayer));
				PlayerDisplay.getInstance().draw();
				draw();
			}
		});
		final String string;
		if (currPlayer == players.size()-1) {
			string = "close";
		} else string = "next_player";
		
		JButton nextButton = new JButton(SystemMessagesHandler.getInstance().getMessages().getString(string));
		nextButton.setMnemonic('e');
		nextButton.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent arg0) {
				currTab = 0;
				currPlayer++;
				if (!string.equals("close")) {
					Level.getInstance().setAktualPlayer(players.get(currPlayer));
				} else {
					Level.getInstance().setAktualPlayer(firstPlayer);
				}
				PlayerDisplay.getInstance().draw();
				draw();
			}
			
		});

		buttonPane.add(Box.createHorizontalGlue());
		buttonPane.add(previousButton);
		buttonPane.add(Box.createRigidArea(new Dimension(20,0)));
		buttonPane.add(nextButton);
		
		
		return buttonPane;
		
	}
	
	public boolean isStarted() {
		return started;
	}
	
	public boolean isComplete() {
		return complete;
	}
	
	public void reset() {
		players = null;
		
		started = false;
		complete = false;
		
		currPlayer = 0;
		currTab = 0;
	}

	public void draw() {
		if (players != null)
			draw(players);
	}
	
	private List<String> getWeaponNames() {
		java.util.ArrayList<String> weaponList = new java.util.ArrayList<String>();
		try {
			BufferedReader in = new BufferedReader(new InputStreamReader(
			getClass().getClassLoader().getResourceAsStream("dolf/objects/weapons/weapons.index")));
			String weapon = null;
			while ((weapon = in.readLine()) != null) {
				if(weapon.charAt(0)!='#') weaponList.add(weapon);
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return weaponList;
	}
	private LinkedList<LinkedList<wAttrib>> getLists(List<String> l) {
		LinkedList<LinkedList<wAttrib>> list = new LinkedList<LinkedList<wAttrib>>();

		//waffenliste durchgehen und eintragen
		for (int i = 0; i < l.size(); i++) {
			final Class<?> b;
			final String name;
			final String desc;
			final String type;
			final Integer price;
			final ImageIcon icon;
			try {
				b = Class.forName(l.get(i));
				name = (b.getField("Name").get(String.class)).toString();
				desc = (b.getField("Description").get(String.class)).toString();
				type = (b.getField("WeaponType").get(String.class)).toString();
				price = (Integer) (b.getField("Price").get(Integer.class));
				icon = (javax.swing.ImageIcon) (b.getField("Icon").get(javax.swing.ImageIcon.class));

				int j = 0;
				for (; j < list.size(); j++) {
					wAttrib tmp = list.get(j).get(0);
					if (type.equals(tmp.type)) {
						list.get(j).add(new wAttrib(l.get(i),name,desc,type,price,icon));
						break;
					} 

				}
				if (j == list.size()) {
					list.add(new LinkedList<wAttrib>());
					list.get(j).add(new wAttrib(l.get(i),name,desc,type,price,icon));
				}
			}
			catch (Exception e) {
				System.err.println("weapon "+ l.get(i) +" not found");
				e.printStackTrace();
			}
		}
		
		return list;
	}
}
